package com.order.itemcategoryproject.controller;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.order.itemcategoryproject.config.StringToTimestampConverter;
import com.order.itemcategoryproject.pojo.*;
import com.order.itemcategoryproject.pojo.VO.dAccInvAvaGl;
import com.order.itemcategoryproject.pojo.VO.dBlOrderDtOnlineImportVO;
import com.order.itemcategoryproject.pojo.VO.dBlOrderDtOnlineVo;
import com.order.itemcategoryproject.service.DBlOrderDtOnlineService;
import com.order.itemcategoryproject.service.DBlOrderHdOnlineService;
import com.order.itemcategoryproject.service.dArcItemService;
import com.order.itemcategoryproject.service.dArcStaffService;
import com.order.itemcategoryproject.utils.AjaxResult;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.transaction.Transactional;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.URI;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import static com.order.itemcategoryproject.utils.ParseUrl.getUrl;

@RestController
@RequestMapping("/detail")
public class DBlOrderDtOnlineController {

    @Autowired
    private DBlOrderDtOnlineService DBlOrderDtOnlineService;
    @Autowired
    private DBlOrderHdOnlineService dBlOrderHdOnlineService;
    @Autowired
    private dArcItemService dArcItemService;
    @Autowired
    private dArcStaffService dArcStaffService;

    private static final String imgUrl = "https://newerp.mumuso.com/UploadFile";


    /**
     * 添加订单详情信息
     *
     * @param detail
     * @return
     */
    @PostMapping("/insertOrderDetail/{currentLanguage}")
    public AjaxResult insertOrderDetailInfo(@PathVariable String currentLanguage, @RequestBody dBlOrderDtOnline detail, HttpServletRequest request) {
        String queryString = request.getQueryString();
        String staffID = getUrl(queryString, "StaffID");

        // 获取到当前客户对象
        dArcStaff staffInfoByStaId = dArcStaffService.getStaffInfoByStaId(staffID);

        if (StringUtils.isBlank(staffID)) {
            return AjaxResult.error("参数未被定义!!!!!!");
        }
        if (ObjectUtils.isEmpty(detail)) {
            return AjaxResult.error("当前操作有误，获取不到要添加的商品信息，请联系信息部!!!!");
        }
        // 根据商品编号获取该商品信息
        // 获取到商品对象
        // 总库存 = 已经入库+即将入库的商品
        int totalStock = 0;
        dArcItem dArcItem = null;
        if (ObjectUtils.isNotEmpty(staffInfoByStaId) && StringUtils.isNotBlank(staffInfoByStaId.getCus_segmentation())) {
            dArcItem = dArcItemService.selectOneItemById(detail.getItemId(), staffID, currentLanguage, staffInfoByStaId.getCus_segmentation());
        } else {
            return AjaxResult.error("未获取到国际客户，当前还未对国内客户资料完善,终止此操作!!!!!!");
        }
        if (ObjectUtils.isNotEmpty(dArcItem)) {
            List<dAccInvAvaGl> dAccInvAvaGl = dArcItem.getDAccInvAvaGl();
            for (dAccInvAvaGl accInvAvaGl : dAccInvAvaGl) {
                if ("已经入库".equals(accInvAvaGl.getSource()) || "预估入库".equals(accInvAvaGl.getSource())) {
                    totalStock += accInvAvaGl.getInventory();
                }
            }
        }

        // 得到总库存的时候，将前端想要加购的数量进行比较 看库存是否够
        if (detail.getItemOrderNum() > totalStock) {
            // 根据客户名称获取客户信息
            dArcStaff dArcStaff = dArcStaffService.getstaffInfoByName(detail.getCreateStaffId());
            List<dArcItem> dArcItems = null;
            if (ObjectUtils.isNotEmpty(dArcStaff) && StringUtils.isNotBlank(dArcStaff.getCus_segmentation())) {
                dArcItems = dArcItemService.selectAllItemInfoByOrderIdAndCreateStaffId(detail.getOrderId(),
                        detail.getCreateStaffId(),
                        dArcStaff.getStaffId(), currentLanguage, dArcStaff.getCus_segmentation());
            } else {
                return AjaxResult.error("未获取到国际客户，当前还未对国内客户资料完善,终止此操作!!!!!!");
            }
            List<dBlOrderDtOnline> allOrderDetailByOrderId = DBlOrderDtOnlineService.getAllOrderDetailByOrderId(detail.getOrderId());
            for (int i = 0; i < dArcItems.size(); i++) {
                for (int j = 0; j < allOrderDetailByOrderId.size(); j++) {
                    if (!dArcItems.get(i).getItemId().equals(allOrderDetailByOrderId.get(j).getItemId())) {
                        continue;
                    }
                    dArcItems.get(i).setOrderQuantity(allOrderDetailByOrderId.get(j).getItemOrderNum());
                }
            }
            return AjaxResult.error("很遗憾，当前库存不足，当前商品总库存为【" + totalStock + "】!!!!!", dArcItems);
        }

        // 通过订单明细订单编号获取订单状态，如果状态为已完成，那么就不可以在更新数量
        DBlOrderHdOnline orderinfoByOrderId = dBlOrderHdOnlineService.getOrderinfoByOrderId(detail.getOrderId());

        // 获取到订单主表信息 判断状态是否已经完成
        if ("001".equals(orderinfoByOrderId.getOrderStatus())) {
            return AjaxResult.error("当前订单【" + detail.getOrderId() + "】状态为已完成，不能在对此订单操作!!!!!");
        }

        // 如果顾客在进行减减操作的话 当数量为0时删除该明细信息
        if (detail.getItemOrderNum() == 0) {
            // 当数量为0时证明已经不想将此商品订购啦 那么这个时候就可以将这个商品删除啦

            HashMap<String, Object> orderDetailInfoMap = new HashMap<>();
//            int effectLine = DBlOrderDtOnlineService.deleteOrderDetailByOrderIdAndItemId(detail.getOrderId(), detail.getItemId());
            int effectLine = DBlOrderDtOnlineService.updateOrderDetailByItemIdAndOrderId(detail.getOrderId(), detail.getItemId());
            int effectRow = dBlOrderHdOnlineService.updateOrderTotalNumAndTotalPrice(orderinfoByOrderId.getOrderId());
            if (effectRow > 0) {
                orderinfoByOrderId = dBlOrderHdOnlineService.getOrderinfoByOrderId(orderinfoByOrderId.getOrderId());
                orderDetailInfoMap.put("orderInfo", orderinfoByOrderId);
            }
            if (effectLine > 0) {
                // 重新获取该订单下所有明细 todo 问题1： 没有根据当前客户 会获取到
                List<dArcItem> dArcItems = null;
                if (ObjectUtils.isNotEmpty(staffInfoByStaId) && StringUtils.isNotBlank(staffInfoByStaId.getCus_segmentation())) {
                    dArcItems = dArcItemService.selectAllItemInfoByOrderIdAndCreateStaffId(detail.getOrderId(),
                            detail.getCreateStaffId(), staffID, currentLanguage, staffInfoByStaId.getCus_segmentation());
                } else {
                    return AjaxResult.error("未获取到国际客户，当前还未对国内客户资料完善,终止此操作!!!!!!");
                }
                List<dBlOrderDtOnline> allOrderDetailByOrderId = DBlOrderDtOnlineService.getAllOrderDetailByOrderId(detail.getOrderId());
                for (int i = 0; i < dArcItems.size(); i++) {
                    for (int j = 0; j < allOrderDetailByOrderId.size(); j++) {
                        if (!dArcItems.get(i).getItemId().equals(allOrderDetailByOrderId.get(j).getItemId())) {
                            continue;
                        }
                        dArcItems.get(i).setOrderQuantity(allOrderDetailByOrderId.get(j).getItemOrderNum());
                    }
                }
                orderDetailInfoMap.put("itemList", dArcItems);
                return AjaxResult.success(500, "你已经将该商品【" + detail.getItemName() + "】订购数量减为0，将为你将该商品删除!!!!!", orderDetailInfoMap);
            }
        }

        // 根据商品编号以及制单人编号查询数据库是否有当前对象
        dBlOrderDtOnline orderDetail = DBlOrderDtOnlineService.getOrderDetailInfoByItemIdAndCreateStaffId(detail.getItemId(), detail.getCreateStaffId(), detail.getOrderId());

        // 获取到已经入库的数量
        int beenIntoStorageNumber = 0;
        // 只有即将入库数量的 那么就直接将数量添加到即将入库货品定量
        int onlyHavejjrkNumber = 0;
        int jjrkhpdlNumber = 0;
        // 通过当前导入的商品通过商品编号获取商品信息
        if (ObjectUtils.isNotEmpty(dArcItem)) {
            // 如果当前商品存在，那么获取当前商品的入库数量
            for (dAccInvAvaGl dAccInvAvaGl1 : dArcItem.getDAccInvAvaGl()) {
                if ("已经入库".equals(dAccInvAvaGl1.getSource())) {
                    beenIntoStorageNumber += dAccInvAvaGl1.getInventory();
                }
                if ("预估入库".equals(dAccInvAvaGl1.getSource())) {
                    onlyHavejjrkNumber += dAccInvAvaGl1.getInventory();
                }
            }
        }
        // 将用户选购的数量选择进来（这是操作单个商品的
        // 判断当前选购数量是否大于当前已经入库数量
        // 判断即将入库的数量是否未0

        // 判断是否是第一次添加商品 判断是否存在
        if (ObjectUtils.isNotEmpty(orderDetail)) {
            if (beenIntoStorageNumber == 0 && onlyHavejjrkNumber != 0) {
                if (orderDetail.getJjrkhpdl() == 0) {
                    // 通过当前信息获取当前数据库中是否已经存在
                    if (ObjectUtils.isNotEmpty(orderDetail)) {
                        jjrkhpdlNumber += onlyHavejjrkNumber;
                        DBlOrderDtOnlineService.updateOrderDetailjjrkhpdl(detail.getItemId(), detail.getCreateStaffId(),
                                jjrkhpdlNumber, detail.getOrderId());
                    } else {
                        detail.setJjrkhpdl(onlyHavejjrkNumber);
                    }
                } else {
                    // 首先获取到当前商品的即将入库货品定向数量
                    jjrkhpdlNumber += (detail.getItemOrderNum() - beenIntoStorageNumber) + detail.getJjrkhpdl();
                    DBlOrderDtOnlineService.updateOrderDetailjjrkhpdl(detail.getItemId(), detail.getCreateStaffId(),
                            jjrkhpdlNumber, detail.getOrderId());
                }
            } else {
                if (detail.getItemOrderNum() > beenIntoStorageNumber) {
                    if (detail.getJjrkhpdl() == 0) {
                        // 通过当前信息获取当前数据库中是否已经存在
                        if (ObjectUtils.isNotEmpty(detail)) {
                            jjrkhpdlNumber += (detail.getItemOrderNum() - beenIntoStorageNumber);
                            DBlOrderDtOnlineService.updateOrderDetailjjrkhpdl(detail.getItemId(), detail.getCreateStaffId(),
                                    jjrkhpdlNumber, detail.getOrderId());
                        } else {
                            detail.setJjrkhpdl(onlyHavejjrkNumber);
                        }
                    } else {
                        // 首先获取到当前商品的即将入库货品定向数量
                        jjrkhpdlNumber += (detail.getItemOrderNum() - beenIntoStorageNumber) + detail.getJjrkhpdl();
                        DBlOrderDtOnlineService.updateOrderDetailjjrkhpdl(detail.getItemId(), detail.getCreateStaffId(),
                                jjrkhpdlNumber, detail.getOrderId());
                    }
                } else {
                    DBlOrderDtOnlineService.updateOrderDetailjjrkhpdl(detail.getItemId(), detail.getCreateStaffId(),
                            0, detail.getOrderId());
                }
            }
        } else {
            if (beenIntoStorageNumber == 0 && onlyHavejjrkNumber != 0) {
                detail.setJjrkhpdl(detail.getItemOrderNum());
            } else {
                if (detail.getItemOrderNum() > beenIntoStorageNumber) {
                    jjrkhpdlNumber += (detail.getItemOrderNum() - beenIntoStorageNumber);
                    detail.setJjrkhpdl(jjrkhpdlNumber);
                } else {
                    detail.setJjrkhpdl(0);
                }
            }
        }

        // 如果大于当前入库数量，那么就将多出的数量添加到新字段中 因为多出的可能就是

        // 判断当前对象是否为空
        if (ObjectUtils.isEmpty(orderDetail)) {
            // 如果没有当前对象，那么就添加当前商品
            // 如果当前对象为空，证明当前数据库没有此对象，执行新建方法
            // 获取当前时间 年月日 时分秒
            Timestamp currentTimestamp = new Timestamp(System.currentTimeMillis());
            detail.setUptime(currentTimestamp);


            // 当前传入对象不为空，则继续下面操作
            int effectLine = DBlOrderDtOnlineService.insertOrderDetailInfo(detail);
            if (effectLine > 0) {
                return AjaxResult.success("已将商品订购数量明细信息添加到订单表!!!!!");
            } else {
                return AjaxResult.error("添加商品订购数量失败!!!!");
            }
        } else {
            // 如果有当前对象，那么就更新当前商品的订购数量
            int effLine = DBlOrderDtOnlineService.updateOrderDetailOrderNumber(detail.getItemId(),
                    detail.getCreateStaffId(), detail.getItemOrderNum(), detail.getOrderId());
            if (effLine > 0) {
                return AjaxResult.success("当前商品编号为【" + detail.getItemId() + "】的商品订购数量已更新成功!!!!!!");
            } else {
                return AjaxResult.error("当前商品编号为【" + detail.getOrderId() + "】的商品订购数量更新失败!!!!");
            }
        }


    }


    /**
     * 通过订单编号获取到所有明细信息，获取到所有明细之后进行计算 然后赋值给主表
     *
     * @param orderId
     * @return
     */
    @GetMapping("/selectDetailInfoByOrderId/{orderId}")
    public AjaxResult selectDetailInfoByOrderId(@PathVariable String orderId) {
        // 根据订单编号获取创建的订单信息
        DBlOrderHdOnline orderinfo = dBlOrderHdOnlineService.getOrderinfoByOrderId(orderId);
        // 通过订单编号获取该订单下所有明细信息
        // 获取到当前订单下所有明细信息
        List<dBlOrderDtOnline> details = DBlOrderDtOnlineService.getAllOrderDetailByOrderId(orderId);


        if (ObjectUtils.isEmpty(details)) {
            return AjaxResult.error("当前客户订单下并没有进行订购商品!!!!!");
        }
        // 订购总数量 动态变化
        int totalNum = details.stream()
                .mapToInt(dBlOrderDtOnline::getItemOrderNum)
                .sum();

        // 订单总价格 动态变化
        double totalPrice = details.stream()
                .mapToDouble(detail -> detail.getItemOrderNum() * detail.getItemPrice())
                .sum();

        // 订单总体积（当前明细里所有商品的体积之和）
        double totalVolume = details.stream()
                .mapToDouble(detail -> detail.getItemVolume() * detail.getItemOrderNum())
                .sum();

        // 订单总重量
        double totalWeight = details.stream()
                .mapToDouble(detail -> detail.getItemWeight() * detail.getItemOrderNum())
                .sum();


        // 使用 BigDecimal 保留两位小数 订购总价格
        BigDecimal totalPriceBD = BigDecimal.valueOf(totalPrice);
        totalPriceBD = totalPriceBD.setScale(2, RoundingMode.HALF_UP);


        // 使用BigDecimal保留六位小数 订购商品明细信息的总体积计算
        BigDecimal totalVolumeBD = BigDecimal.valueOf(totalVolume);
        totalVolumeBD = totalVolumeBD.setScale(6, RoundingMode.HALF_UP);

        // 使用BigDecimal保留六位小数 订购商品明细信息的总重量计算
        BigDecimal totalWeightBD = BigDecimal.valueOf(totalWeight);
        totalWeightBD = totalWeightBD.setScale(6, RoundingMode.HALF_UP);


        orderinfo.setTotalNum(totalNum);
        orderinfo.setTotalPrice(totalPriceBD.doubleValue());
        orderinfo.setTotalVolume(totalVolumeBD.doubleValue());
        orderinfo.setTotalWeight(totalWeightBD.doubleValue());

        int effectLine = dBlOrderHdOnlineService.updateOrderInfoByOrderId(
                orderId, totalNum, totalPriceBD.doubleValue(), totalVolumeBD.doubleValue(),
                totalWeightBD.doubleValue());
        if (effectLine > 0) {
            return AjaxResult.success(orderinfo);
        } else {
            return AjaxResult.error("更新失败!!!!!");
        }
    }


    /**
     * 根据订单编号获取该订单下所有商品信息
     *
     * @param orderId
     * @return
     */
    @GetMapping("/selectOrderDetailById/{orderId}")
    public AjaxResult getAllOrderDetailByOrderId(@PathVariable String orderId) {
        if (StringUtils.isEmpty(orderId)) {
            return AjaxResult.error("操作有误，请先点击左侧最近订单渲染之后在点击此按钮!!!!!");
        }

        List<dBlOrderDtOnline> detail = DBlOrderDtOnlineService.getAllOrderDetailByOrderId(orderId);
        // 判断获取到的订单明细是否为空
        if (ObjectUtils.isEmpty(detail)) {
            return AjaxResult.error("当前订单还未生成订单明细信息!!!!!");
        }

        // 如果不为空的时候，那么就将明细信息返回
        return AjaxResult.success(detail);
    }


    /**
     * 根据订单编号和商品编号将该订单明细删除
     *
     * @param orderId
     * @param itemId
     * @return
     */
    @DeleteMapping("/deleteDetailByOrderIdAndItemId")
    public AjaxResult deleteItemDetailByOrderIdAndItemId(@RequestParam("orderId") String orderId, @RequestParam("itemId") String itemId) {
        if (StringUtils.isBlank(orderId) || StringUtils.isBlank(itemId)) {
            return AjaxResult.error("未被定义的参数，操作有误!!!!!");
        }

//        int effectLine = DBlOrderDtOnlineService.deleteOrderDetailByOrderIdAndItemId(orderId, itemId);
        int effectLine = DBlOrderDtOnlineService.updateOrderDetailByItemIdAndOrderId(orderId, itemId);

        if (effectLine > 0) {
            return AjaxResult.success("已将该订单信息删除!!!!");
        } else {
            return AjaxResult.error("删除失败!!!!");
        }
    }

    /**
     * 根据订单编号和商品编号将该订单明细删除
     *
     * @param orderId
     * @param itemId
     * @return
     */
    @DeleteMapping("/deleteImportDetailByOrderIdAndItemId")
    public AjaxResult deleteItemImportDetailByOrderIdAndItemId(@RequestParam("orderId") String orderId, @RequestParam("itemId") String itemId) {
        if (StringUtils.isBlank(orderId) || StringUtils.isBlank(itemId)) {
            return AjaxResult.error("未被定义的参数，操作有误!!!!!");
        }

//        int effectLine = DBlOrderDtOnlineService.deleteOrderDetailByOrderIdAndItemId(orderId, itemId);
        int effectLine = DBlOrderDtOnlineService.updateImportOrderDetailByItemIdAndOrderId(orderId, itemId);

        if (effectLine > 0) {
            return AjaxResult.success("已将该订单信息删除!!!!");
        } else {
            return AjaxResult.error("删除失败!!!!");
        }
    }


    /**
     * 通过订单编号获取该制单人下的所有订单商品详情信息
     *
     * @param orderId
     * @return
     */
    @GetMapping("/getAllOrderDetailInfoById/{orderId}/{currentLanguage}")
    public AjaxResult getAllOrderDetailInfoByCreateStaffId(@PathVariable String orderId,
                                                           @PathVariable String currentLanguage,
                                                           HttpServletRequest request) {
        String queryString = request.getQueryString();
        String staffID = getUrl(queryString, "StaffID");
        if (StringUtils.isBlank(staffID)) {
            return AjaxResult.error("当前参数未被定义，请联系信息部!!!!");
        }

        if (StringUtils.isBlank(orderId)) {
            return AjaxResult.error("未被定义的参数");
        }

        List<dBlOrderDtOnline> detailInfoByCreateStaff = DBlOrderDtOnlineService.getAllOrderDetailByOrderId(orderId);
        if (ObjectUtils.isEmpty(detailInfoByCreateStaff)) {
            return AjaxResult.error("当前订单【" + orderId + "】并没有订购商品，所以未查询到商品详情信息!!!!!");
        }

        // 如果不为空，那么就获取当前的图片路劲存储到本地
        // 通过制单人编号获取制单人信息
        dArcStaff staffInfo = dArcStaffService.getStaffInfoByStaId(staffID);
        String errorMsg = null;
        dArcItem dArcItem = null;
        for (dBlOrderDtOnline dBlOrderDtOnline : detailInfoByCreateStaff) {
            // 通过订单编号获取当前SKU商品信息
            if (ObjectUtils.isEmpty(dBlOrderDtOnline)) {
                break;
            }
            if (ObjectUtils.isNotEmpty(staffInfo) && StringUtils.isNotBlank(staffInfo.getCus_segmentation())) {
                dArcItem = dArcItemService.selectAllItemInfo(dBlOrderDtOnline.getItemId(),
                        staffID, currentLanguage, staffInfo.getCus_segmentation());
                if (ObjectUtils.isEmpty(dArcItem)) {
                    break;
                }
            } else {
                errorMsg += "当前客户不是国际客户，当前未对国内客户开放，终止此操作!!!!";
            }
            if (StringUtils.isNotBlank(dArcItem.getDArcItemPic().getMainPic())) {
                dBlOrderDtOnline.setItemImgUrl(dArcItem.getDArcItemPic().getMainPic());
            }
        }

        if (StringUtils.isNotBlank(errorMsg)) {
            return AjaxResult.error(errorMsg);
        } else {
            return AjaxResult.success(detailInfoByCreateStaff);
        }
    }


    /**
     * 根据订单编号获取该订单下所有的导入的订单明细信息
     *
     * @param orderId
     * @return
     */
    @GetMapping("/getAllImportOrderDetailInfos/{orderId}/{currentLanguage}")
    public AjaxResult getAllImportOrderDetailInfosByOrderId(@PathVariable String orderId,
                                                            @PathVariable String currentLanguage,
                                                            HttpServletRequest request) {
        String queryString = request.getQueryString();
        String staffID = getUrl(queryString, "StaffID");

        if (StringUtils.isBlank(orderId) || StringUtils.isBlank(staffID)) {
            return AjaxResult.error("未被定义的参数");
        }
        List<dBlOrderDtOnline> detailInfoByCreateStaff = DBlOrderDtOnlineService.getAllImportOrderInfosByOrderId(orderId);
        if (ObjectUtils.isEmpty(detailInfoByCreateStaff)) {
            return AjaxResult.error("当前订单【" + orderId + "】并没有导入商品，所以未查询到导入的商品信息!!!!!");
        }

        // 通过制单人编号获取制单人信息
        dArcStaff staffInfo = dArcStaffService.getStaffInfoByStaId(staffID);
        String errorMsg = null;
        // 如果不为空，那么就获取当前的图片路劲存储到本地
        dArcItem dArcItem = null;
        for (dBlOrderDtOnline dBlOrderDtOnline : detailInfoByCreateStaff) {
            // 通过订单编号获取当前SKU商品信息
            if (ObjectUtils.isEmpty(dBlOrderDtOnline)) {
                break;
            }
            if (ObjectUtils.isNotEmpty(staffInfo) && StringUtils.isNotBlank(staffInfo.getCus_segmentation())) {
                dArcItem = dArcItemService.selectAllItemInfo(dBlOrderDtOnline.getItemId(),
                        staffID, currentLanguage, staffInfo.getCus_segmentation());
            } else {
                errorMsg += "当前客户不是国际客户，当前未对国内客户开放，终止此操作!!!!";
            }
            dBlOrderDtOnline.setItemImgUrl(dArcItem.getDArcItemPic().getMainPic());
        }

        if (StringUtils.isNotBlank(errorMsg)) {
            return AjaxResult.error(errorMsg);
        } else {
            return AjaxResult.success(detailInfoByCreateStaff);
        }
    }


    /**
     * 导出该客户下所有的订单详情内容
     *
     * @param details
     * @return
     */
    @PostMapping("/exportDetailInfo")
    public AjaxResult exportOrderInfoDetailExcel(@RequestBody List<dBlOrderDtOnline> details, HttpServletResponse response) {
        //返回输出流_excel格式
        try {
            response.setContentType("application/octet-stream");
            String fileName = new URI(null, "客户订单详情", null).toASCIIString();
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
        } catch (Exception e) {
            return AjaxResult.error(e.getMessage());
        }

        // 计算合计行数据
        int totalQuantity = 0;
        double totalPrice = 0;
        double totalVolume = 0;
        double singleTotalPrice = 0;
        for (dBlOrderDtOnline detail : details) {
            totalQuantity += detail.getItemOrderNum();
            totalPrice += detail.getItemOrderNum() * detail.getItemPrice();
            totalVolume += detail.getItemVolume() * detail.getItemOrderNum();
            singleTotalPrice += detail.getSingleTotalPrice();
        }

        BigDecimal totalPriceBD = BigDecimal.valueOf(totalPrice);
        totalPriceBD = totalPriceBD.setScale(2, RoundingMode.HALF_UP);

        BigDecimal totalVolumeBD = BigDecimal.valueOf(totalVolume);
        totalVolumeBD = totalVolumeBD.setScale(6, RoundingMode.HALF_UP);

        BigDecimal singleTotalPriceBD = BigDecimal.valueOf(singleTotalPrice);
        singleTotalPriceBD = singleTotalPriceBD.setScale(2, RoundingMode.HALF_UP);

        // 创建合计行对象
        dBlOrderDtOnline totalRow = new dBlOrderDtOnline();
        totalRow.setItemOrderNum(totalQuantity);
        totalRow.setItemPrice(totalPriceBD.doubleValue());
        totalRow.setItemVolume(totalVolumeBD.doubleValue());
        totalRow.setSingleTotalPrice(singleTotalPriceBD.doubleValue());

        details.add(totalRow);

        try {
            EasyExcel.write(response.getOutputStream(), dBlOrderDtOnline.class).autoCloseStream(Boolean.FALSE).registerConverter(new StringToTimestampConverter()).sheet("客户订单详情").doWrite(details);
            return AjaxResult.success("数据导出成功!!!!");
        } catch (IOException e) {
            return AjaxResult.error(e.getMessage());
        }
    }


    /**
     * 导出该客户下统计的订单内容
     *
     * @param details
     * @return
     */
    @PostMapping("/exportDetailSumInfo")
    public AjaxResult exportOrderInfoSumDetailExcel(@RequestBody List<dBlOrderDtOnlineVo> details, HttpServletResponse response) {
        //返回输出流_excel格式
        try {
            response.setContentType("application/octet-stream");
            String fileName = new URI(null, "客户订单详情", null).toASCIIString();
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
        } catch (Exception e) {
            return AjaxResult.error(e.getMessage());
        }

        // 计算合计行数据
        int totalQuantity = 0;
        double totalPrice = 0;
        for (dBlOrderDtOnlineVo detail : details) {
            totalQuantity += detail.getTotalNum();
            totalPrice += detail.getTotalPrice();
        }

        // 创建合计行对象
        dBlOrderDtOnlineVo totalRow = new dBlOrderDtOnlineVo();
        totalRow.setTotalNum(totalQuantity);
        totalRow.setTotalPrice(totalPrice);

        details.add(totalRow);

        try {
            EasyExcel.write(response.getOutputStream(), dBlOrderDtOnlineVo.class).autoCloseStream(Boolean.FALSE).registerConverter(new StringToTimestampConverter()).sheet("客户订单类别统计详情").doWrite(details);
            return AjaxResult.success("数据导出成功!!!!");
        } catch (IOException e) {
            return AjaxResult.error(e.getMessage());
        }
    }


    /**
     * 根据客户编号获取该客户下所创建的所有订单明细
     *
     * @param orderId
     * @return
     */
    @GetMapping("/selectAllOrderGroupBySmClassId/{orderId}")
    public AjaxResult selectAllOrderGroupBySmClassId(@PathVariable String orderId) {
        if (StringUtils.isBlank(orderId)) {
            return AjaxResult.error("参数未被定义!!!!!!!");
        }
        List<dBlOrderDtOnlineVo> dBlOrderDtOnlines = DBlOrderDtOnlineService.selectAllOrderGroupBySmClassId(orderId);
        if (ObjectUtils.isEmpty(dBlOrderDtOnlines)) {
            return AjaxResult.error("当前客户下该订单【" + orderId + "】并没有订单订购详情信息!!!!!!!");
        }
        return AjaxResult.success(dBlOrderDtOnlines);
    }


    /**
     * 根据订单编号以及客户名称和商品编号来更新当前订单备注内容
     * 之所以使用这么多条件是因为一个商品可以被多个订单和客户进行采购
     *
     * @param createStaffId
     * @param orderId
     * @param itemId
     * @param remark
     * @return
     */
    @PutMapping("/updateOrderRemarkByIdAndCreateStaffId")
    public AjaxResult updateOrderDetailByOrderIdAndCid(@RequestParam("createStaffId") String createStaffId, @RequestParam("orderId") String orderId,
                                                       @RequestParam("itemId") String itemId, @RequestParam("remark") String remark) {

        // 首先判断这些参数都不为空
        if (StringUtils.isBlank(createStaffId) || StringUtils.isBlank(orderId) || StringUtils.isBlank(itemId) || StringUtils.isBlank(remark)) {
            return AjaxResult.error("参数未被定义!!!!!!!");
        }

        int effectLine = DBlOrderDtOnlineService.updateItemRemarkByCidAndOidAndItemId(createStaffId, orderId, itemId, remark);

        if (effectLine > 0) {
            return AjaxResult.success("当前商品【" + itemId + "】备注已添加!!!!!!");
        } else {
            return AjaxResult.error("当前商品【" + itemId + "备注添加失败!!!!!");
        }
    }

    /**
     * 导入订单明细信息
     *
     * @param file
     * @return
     */
    @PostMapping("/import")
    public AjaxResult importDetailInfo(@RequestParam("file") MultipartFile file) {
        // 检查文件类型，确保是Excel文件
        if (!file.getContentType().equals("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")) {
            return AjaxResult.error("只能导入Excel文件!!!!!!");
        }

        List<dBlOrderDtOnlineImportVO> details = new ArrayList<>();

        try {
            EasyExcel.read(file.getInputStream(), dBlOrderDtOnlineImportVO.class, new AnalysisEventListener<dBlOrderDtOnlineImportVO>() {

                @Override
                public void invoke(dBlOrderDtOnlineImportVO dBlOrderDtOnline, AnalysisContext analysisContext) {
                    details.add(dBlOrderDtOnline);
                }

                @Override
                public void doAfterAllAnalysed(AnalysisContext analysisContext) {

                }
            }).registerConverter(new StringToTimestampConverter()).sheet().doRead();
        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.error("文件导入失败 " + e.getMessage());
        }
        return AjaxResult.success("文件导入成功!!!!", details);
    }


    /**
     * 批量添加订单信息
     * 这是根据导入进来的
     *
     * @param dBlOrderDtOnlines
     * @param request
     * @return
     */
    @PostMapping("/patchInsertInfo/{orderId}/{currentLanguage}")
    @Transactional
    public AjaxResult patchInsertOrderDetailInfo(@PathVariable String orderId,
                                                 @PathVariable String currentLanguage,
                                                 @RequestBody List<dBlOrderDtOnline> dBlOrderDtOnlines,
                                                 HttpServletRequest request) {
        String queryString = request.getQueryString();
        String staffID = getUrl(queryString, "StaffID");

        // 根据staffId获取当前客户名称
        dArcStaff staffInfoByStaId = dArcStaffService.getStaffInfoByStaId(staffID);

        if (ObjectUtils.isEmpty(dBlOrderDtOnlines)) {
            return AjaxResult.error("当前导入数据为空");
        }
        // 判断当前参数是否为空
        if (StringUtils.isBlank(staffID) && StringUtils.isBlank(orderId)) {
            return AjaxResult.error("参数未被定义!!!!!");
        }


        // 如果不为空啦 那么就开始做相应的操作
        // 遍历这个集合 得到订单明细信息
        // 获取到单个订单明细信息
        List<dBlOrderDtOnline> details = new ArrayList<>();
        // 中包数量
        int midPackNumber = 0;
        // 最大库存数
        int totalStock = 0;
        String errorMsgInfo = null;
        dArcItem dArcItem = null;
        for (dBlOrderDtOnline dBlOrderDtOnline : dBlOrderDtOnlines) {
            // 判断是否是当前订单下的订单
            if (!orderId.equals(dBlOrderDtOnline.getOrderId())) {
                return AjaxResult.error("抱歉，你当前导入的并非属于当前订单【" + orderId + "】下的明细信息!!!!!!");
            }
            if (!staffID.equals(dBlOrderDtOnline.getCreateStaffId())) {
                return AjaxResult.error("抱歉，你当前导入的并非属于当前客户【" + staffID + "】下的明细信息!!!!!!");
            }

            // 通过订单明细订单编号获取订单状态，如果状态为已完成，那么就不可以在更新数量
            DBlOrderHdOnline orderinfoByOrderId = dBlOrderHdOnlineService.getOrderinfoByOrderId(dBlOrderDtOnline.getOrderId());
            if ("001".equals(orderinfoByOrderId.getOrderStatus())) {
                return AjaxResult.error("当前订单【" + dBlOrderDtOnline.getOrderId() + "】状态为已完成，不能在对此订单操作!!!!!");
            }
            if (ObjectUtils.isNotEmpty(dBlOrderDtOnline)) {
                // 如果没有当前对象，那么就添加当前商品
                // 如果当前对象为空，证明当前数据库没有此对象，执行新建方法
                // 获取当前时间 年月日 时分秒
                // 获取传递过来的商品编号 通过商品编号获取商品明细信息

                if (ObjectUtils.isNotEmpty(staffInfoByStaId) && StringUtils.isNotBlank(staffInfoByStaId.getCus_segmentation())) {
                    dArcItem = dArcItemService.selectAllItemInfo(dBlOrderDtOnline.getItemId(), staffID,
                            currentLanguage, staffInfoByStaId.getCus_segmentation());
                } else {
                    errorMsgInfo += "当前客户不是国际客户，当前未对国内客户开放，终止此操作!!!!";
                }
                if (ObjectUtils.isNotEmpty(dArcItem)) {
                    if (ObjectUtils.isNotEmpty(dArcItem.getDArcItemSpecsCodes())) {
                        // 如果当前有这个商品， 那么此时应该获取到当前商品的的中包数量
                        for (dArcItemSpecsCode dArcItemSpecsCode : dArcItem.getDArcItemSpecsCodes()) {
                            if ("002".equals(dArcItemSpecsCode.getPackageType())) {
                                midPackNumber = dArcItemSpecsCode.getSpecsNum();
                            }
                        }
                    } else {
                        midPackNumber = 1;
                    }
                    // 从而获取到当前商品可用最大库存
                    // 总库存 = 已经入库+即将入库的商品
                    List<dAccInvAvaGl> dAccInvAvaGl = dArcItem.getDAccInvAvaGl();
                    for (dAccInvAvaGl accInvAvaGl : dAccInvAvaGl) {
                        if ("已经入库".equals(accInvAvaGl.getSource()) || "预估入库".equals(accInvAvaGl.getSource())) {
                            totalStock += accInvAvaGl.getInventory();
                        }
                    }
                    // 获取到这些之后，然后对当前商品订购数量进行判断，判断当前订购数是否大于当前最大可用库存数量
                    // 如果大于当前最大可用库存数量，那么将订购数量变为最大可用库存数
                    if (dBlOrderDtOnline.getItemOrderNum() > totalStock) {
                        dBlOrderDtOnline.setItemOrderNum(totalStock);
                    } else {
                        // 如果订购数量不是中包数量的倍数，则取最接近的中包数量
                        if (dBlOrderDtOnline.getItemOrderNum() % midPackNumber != 0) {
                            // 计算最接近的中包数量
                            int closesPackQuantity = Math.round((float) dBlOrderDtOnline.getItemOrderNum() / midPackNumber) * midPackNumber;
                            if (closesPackQuantity < midPackNumber) {
                                closesPackQuantity += midPackNumber;
                            }
                            dBlOrderDtOnline.setItemOrderNum(closesPackQuantity);
                        } else {
                            dBlOrderDtOnline.setItemOrderNum(dBlOrderDtOnline.getItemOrderNum());
                        }
                    }

                    dBlOrderDtOnline.setItemId(dBlOrderDtOnline.getItemId().trim());
                    dBlOrderDtOnline.setOrderId(dBlOrderDtOnline.getOrderId().trim());
                    dBlOrderDtOnline.setCreateStaffId(staffInfoByStaId.getStaffName());
                    dBlOrderDtOnline.setItemCaClassName(dArcItem.getDArcCLass().getClassName());
                    dBlOrderDtOnline.setItemBgClassName(dArcItem.getDArcCLass().getBigClassName());
                    dBlOrderDtOnline.setItemMdClassName(dArcItem.getDArcCLass().getMdClassName());
                    dBlOrderDtOnline.setItemSmClassId(dArcItem.getDArcCLass().getSmClassId());
                    dBlOrderDtOnline.setItemSmClassName(dArcItem.getDArcCLass().getSmClassName());
                    dBlOrderDtOnline.setItemName(dArcItem.getItemName());
                    dBlOrderDtOnline.setItemPrice(dArcItem.getDArcReqPrice().getPurchasePrice().doubleValue());

                    // 获取到已经入库的数量
                    int beenIntoStorageNumber = 0;
                    // 只有即将入库数量的 那么就直接将数量添加到即将入库货品定量
                    int onlyHavejjrkNumber = 0;
                    int jjrkhpdlNumber = 0;
                    // 通过当前导入的商品通过商品编号获取商品信息
                    if (ObjectUtils.isNotEmpty(dArcItem)) {
                        // 如果当前商品存在，那么获取当前商品的入库数量
                        for (dAccInvAvaGl dAccInvAvaGl1 : dArcItem.getDAccInvAvaGl()) {
                            if ("已经入库".equals(dAccInvAvaGl1.getSource())) {
                                beenIntoStorageNumber += dAccInvAvaGl1.getInventory();
                            }
                            if ("预估入库".equals(dAccInvAvaGl1.getSource())) {
                                onlyHavejjrkNumber += dAccInvAvaGl1.getInventory();
                            }
                        }
                    }
                    // 将用户选购的数量选择进来（这是操作单个商品的
                    // 判断当前选购数量是否大于当前已经入库数量
                    // 判断即将入库的数量是否未0
                    dBlOrderDtOnline orderDtOnline = DBlOrderDtOnlineService.getOrderDetailInfoByItemIdAndCreateStaffId(dBlOrderDtOnline.getItemId(),
                            dBlOrderDtOnline.getCreateStaffId(), dBlOrderDtOnline.getOrderId());
                    if (ObjectUtils.isNotEmpty(orderDtOnline)) {
                        if (beenIntoStorageNumber == 0 && onlyHavejjrkNumber != 0) {
                            if (orderDtOnline.getJjrkhpdl() == 0 && dBlOrderDtOnline.getItemOrderNum() < totalStock) {
                                // 通过当前信息获取当前数据库中是否已经存在
                                if (ObjectUtils.isNotEmpty(orderDtOnline)) {
                                    jjrkhpdlNumber += onlyHavejjrkNumber;
                                    DBlOrderDtOnlineService.updateOrderDetailjjrkhpdl(dBlOrderDtOnline.getItemId(), dBlOrderDtOnline.getCreateStaffId(),
                                            jjrkhpdlNumber, dBlOrderDtOnline.getOrderId());
                                } else {
                                    dBlOrderDtOnline.setJjrkhpdl(onlyHavejjrkNumber);
                                }
                            } else {
                                // 首先获取到当前商品的即将入库货品定向数量
                                jjrkhpdlNumber += (dBlOrderDtOnline.getItemOrderNum() - beenIntoStorageNumber) + dBlOrderDtOnline.getJjrkhpdl();
                                DBlOrderDtOnlineService.updateOrderDetailjjrkhpdl(dBlOrderDtOnline.getItemId(), dBlOrderDtOnline.getCreateStaffId(),
                                        jjrkhpdlNumber, dBlOrderDtOnline.getOrderId());
                            }
                        } else {
                            if (dBlOrderDtOnline.getItemOrderNum() < totalStock && dBlOrderDtOnline.getItemOrderNum() > beenIntoStorageNumber) {
                                if (orderDtOnline.getJjrkhpdl() == 0) {
                                    // 通过当前信息获取当前数据库中是否已经存在
                                    if (ObjectUtils.isNotEmpty(orderDtOnline)) {
                                        jjrkhpdlNumber += (dBlOrderDtOnline.getItemOrderNum() - beenIntoStorageNumber);
                                        DBlOrderDtOnlineService.updateOrderDetailjjrkhpdl(dBlOrderDtOnline.getItemId(), dBlOrderDtOnline.getCreateStaffId(),
                                                jjrkhpdlNumber, dBlOrderDtOnline.getOrderId());
                                    } else {
                                        dBlOrderDtOnline.setJjrkhpdl(onlyHavejjrkNumber);
                                    }
                                } else {
                                    // 首先获取到当前商品的即将入库货品定向数量
                                    jjrkhpdlNumber += (dBlOrderDtOnline.getItemOrderNum() - beenIntoStorageNumber) + dBlOrderDtOnline.getJjrkhpdl();
                                    DBlOrderDtOnlineService.updateOrderDetailjjrkhpdl(dBlOrderDtOnline.getItemId(), dBlOrderDtOnline.getCreateStaffId(),
                                            jjrkhpdlNumber, dBlOrderDtOnline.getOrderId());
                                }
                            } else {
                                DBlOrderDtOnlineService.updateOrderDetailjjrkhpdl(dBlOrderDtOnline.getItemId(), dBlOrderDtOnline.getCreateStaffId(),
                                        0, dBlOrderDtOnline.getOrderId());
                            }
                        }
                    } else {
                        if (beenIntoStorageNumber == 0 && onlyHavejjrkNumber != 0) {
                            dBlOrderDtOnline.setJjrkhpdl(dBlOrderDtOnline.getItemOrderNum());
                        } else {
                            if (dBlOrderDtOnline.getItemOrderNum() > beenIntoStorageNumber && dBlOrderDtOnline.getItemOrderNum() < totalStock) {
                                jjrkhpdlNumber += (dBlOrderDtOnline.getItemOrderNum() - beenIntoStorageNumber);
                                dBlOrderDtOnline.setJjrkhpdl(jjrkhpdlNumber);
                            } else {
                                dBlOrderDtOnline.setJjrkhpdl(0);
                            }
                        }
                    }


                    if (ObjectUtils.isEmpty(dArcItem.getVolume())) {
                        dBlOrderDtOnline.setItemVolume(0.0);
                    } else {
                        dBlOrderDtOnline.setItemVolume(dArcItem.getVolume());
                    }
                    if (ObjectUtils.isEmpty(dArcItem.getWeight())) {
                        dBlOrderDtOnline.setItemWeight(0.0);
                    } else {
                        dBlOrderDtOnline.setItemWeight(dArcItem.getWeight());
                    }
                    if (StringUtils.isBlank(dArcItem.getRemark())) {
                        dBlOrderDtOnline.setRemark("无");
                    } else {
                        dBlOrderDtOnline.setRemark(dArcItem.getRemark());
                    }
                    if (StringUtils.isBlank(dArcItem.getDArcItemPic().getMainPic())) {
                        dBlOrderDtOnline.setItemImgOnlineUrl("无");
                    } else {
                        dBlOrderDtOnline.setItemImgOnlineUrl(imgUrl + dArcItem.getDArcItemPic().getMainPic());
                    }
                } else {

                }
                Timestamp currentTimestamp = new Timestamp(System.currentTimeMillis());
                dBlOrderDtOnline.setUptime(currentTimestamp);
            }
            // 根据商品编号以及制单人编号查询数据库是否有当前对象
            dBlOrderDtOnline orderDetail = DBlOrderDtOnlineService.getOrderDetailInfoByItemIdAndCreateStaffId(dBlOrderDtOnline.getItemId(),
                    dBlOrderDtOnline.getCreateStaffId(), dBlOrderDtOnline.getOrderId());
            // 获取到当前订单明细对象，获取不到证明当前对象并没有在当前订单下
            // 那么就可以直接添加到可添加列表中
            // 如果当前订单下有当前商品，那么首先获取到当前商品的数量加上导入的数量，其次更新当前商品数量
            if (ObjectUtils.isEmpty(orderDetail)) {
                details.add(dBlOrderDtOnline);
            } else {
                // 不为空证明已经存在当前商品，那么这个时候我们只需要更新订购数量
                // 首先获取到当前存在的订单的订购数量
                int existOrderNumber = orderDetail.getItemOrderNum();
                // 其次将新导入的与已存在的订购数量进行累加
                int totalOrderNumber = dBlOrderDtOnline.getItemOrderNum() + existOrderNumber;
                if (totalOrderNumber > totalStock) {
                    // 如果当前数量大于最大库存数量，那么就只需取最大订购数量
                    dBlOrderDtOnline.setItemOrderNum(totalStock);
                } else {
                    // 如果订购数量不是中包数量的倍数，则取最接近的中包数量
                    if (totalOrderNumber % midPackNumber != 0) {
                        // 计算最接近的中包数量
                        int closesPackQuantity = Math.floorDiv(dBlOrderDtOnline.getItemOrderNum(), midPackNumber) * midPackNumber;
                        dBlOrderDtOnline.setItemOrderNum(closesPackQuantity);
                    } else {
                        dBlOrderDtOnline.setItemOrderNum(totalOrderNumber);
                    }
                }
                // 取完值之后对当前已经存在的订单进行更新订购数量操作
                // 通过staffid获取staffname
                DBlOrderDtOnlineService.updateOrderDetailOrderNumber(dBlOrderDtOnline.getItemId(),
                        dBlOrderDtOnline.getCreateStaffId(), dBlOrderDtOnline.getItemOrderNum(), dBlOrderDtOnline.getOrderId());
            }
        }

        if (StringUtils.isNotBlank(errorMsgInfo)) {
            return AjaxResult.error(errorMsgInfo);
        }

        // 批量添加订单明细信息
        try {
            if (ObjectUtils.isNotEmpty(details)) {
                DBlOrderDtOnlineService.batchInsertDetailInfo(details);
                return AjaxResult.success("已经导入成功并且已更新订单明细信息!!!!!");
            } else {
                return AjaxResult.success("当前导入的商品已存在，已更新当前导入商品的订购数量!!!!!");
            }
        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.error("当前" + e.getMessage());
        }
    }


    @GetMapping("/dowmloadTemplate")
    @ResponseBody
    public ResponseEntity<byte[]> downloadExcel() throws IOException {
        // 从类路径加载模板文件
        Resource resource = new ClassPathResource("static/template.xlsx");

        // 读取文件内容
        byte[] fileContent;
        try (InputStream inputStream = resource.getInputStream()) {
            fileContent = new byte[inputStream.available()];
            inputStream.read(fileContent);
        }

        // 设置响应头
        HttpHeaders headers = new HttpHeaders();
        headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=template.xlsx");

        // 响应文件并设定响应类型
        return ResponseEntity.ok()
                .headers(headers)
                .contentType(MediaType.parseMediaType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"))
                .body(fileContent);
    }
}
